package com.w.wx.service.impls;

import com.w.wx.mapper.LikedMapper;
import com.w.wx.domain.Liked;
import com.w.wx.service.ImagesService;
import com.w.wx.service.RedisService;
import com.w.wx.utils.RedisKeyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class RedisServiceImpl implements RedisService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LikedServiceImpl likedService;
    @Autowired
    private ImagesService imagesService;

    @Override
    public void saveLikedToRedis(Integer objId, String openid,String type) {

        imagesService.addLikedNotice(objId, openid,type);
        String likedKey = RedisKeyUtils.getLikedKey("" + objId, openid,type);
        redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,likedKey, "1");
    }

    @Override
    public void unlikeFromRedis(Integer objId, String openid,String type) {
        String likedKey = RedisKeyUtils.getLikedKey("" + objId, openid,type);
        redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,likedKey, "0");
    }

    @Override
    public void deleteFromRedis(Integer objId, String openid,String type) {
        String key = RedisKeyUtils.getLikedKey("" + objId, openid,type);
        redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, key);
    }

    @Override
    public Long incrementLikedCount(Integer objId,String type, String openid) {
        String key = RedisKeyUtils.getLikedKey("" + objId,type);
        String likedKey = RedisKeyUtils.getLikedKey("" + objId, openid,type);
        //根据定时器时长有延迟
//        if(likedMapper.selectByObjIdAndOpenid(objId,openid,Integer.valueOf(type)).getLikeStatus()==0){
//            redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, key, 1);
//        }


        if("0".equals(redisTemplate.opsForHash().get(RedisKeyUtils.MAP_KEY_USER_LIKED,likedKey))
                || redisTemplate.opsForHash().get(RedisKeyUtils.MAP_KEY_USER_LIKED,likedKey) == null){

           return redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, key, 1);
        }

        return null;
    }

    @Override
    public void decrementLikedCount(Integer objId,String type, String openid) {
        String key = RedisKeyUtils.getLikedKey("" + objId,type);
        String likedKey = RedisKeyUtils.getLikedKey("" + objId, openid,type);
//        if(likedMapper.selectByObjIdAndOpenid(objId,openid,Integer.valueOf(type)).getLikeStatus()==1){
//            redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, key, -1);
//        }

        if("1".equals(redisTemplate.opsForHash().get(RedisKeyUtils.MAP_KEY_USER_LIKED,likedKey))){
            redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, key, -1);
        }
    }

    @Override
    public List<Liked> getLikedDataFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED, ScanOptions.NONE);
        List<Liked> list = new ArrayList<>();
        while (cursor.hasNext()){
            Map.Entry<Object, Object> entry = cursor.next();
            String key = (String) entry.getKey();

            String[] split = key.split("::");
            int status =  Integer.parseInt((String) entry.getValue());


            Liked like = new Liked();
            like.setObjId(Integer.valueOf(split[0]));
            like.setUserOpenid(split[1]);
            like.setType(Integer.valueOf(split[2]));
            like.setLikeStatus(status);

            list.add(like);

            //存到 list 后从 Redis 中删除
           // redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, key);
        }

        return list;
    }

    @Override
    public Cursor<Map.Entry<Object, Object>> getLikedCountFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, ScanOptions.NONE);
        //redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT);
        return cursor;
    }

    @Override
    public int getOneInfoCount(Integer objId, String type) {
        String key = RedisKeyUtils.getLikedKey("" + objId,type);
        return (int)redisTemplate.opsForHash().get(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,key);
    }

    public void saveCountInfo(Integer objId,Integer type,Integer count){
        String key = RedisKeyUtils.getLikedKey("" + objId,""+type);
        redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,key,count);
    }

    @Override
    public void savaInfoFromDb2Re(Integer type) {
        List<Map<String,Object>> likeds = likedService.selectLikedInfoByType(type);
        if (likeds.isEmpty()||likeds.equals("")){
            return;
        }

        Iterator<Map<String,Object>> it = likeds.listIterator();
        while(it.hasNext()){
            Map<String,Object> map = it.next();
            Integer objId =  (Integer) map.get("objId");
            Integer count =  Integer.parseInt(map.get("num_liked").toString());
            log.info("objId:"+objId+"count:"+count+"type:"+type);
            saveCountInfo(objId,type,count);
        }
    }


}
